package multithread.print_by_turn;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class FooBar2 {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    volatile boolean flag = false;


    private int n;

    public FooBar2(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws Exception{
        for (int i = 0; i < n; i++) {
            lock.lock();
            if(flag)
                condition.await();
            // printFoo.run() outputs "foo". Do not change or remove this line.
            printFoo.run();
            flag = true;
            condition.signalAll();
            lock.unlock();
        }
    }

    public void bar(Runnable printBar) throws Exception{
        for (int i = 0; i < n; i++) {
            lock.lock();
            if(!flag)
                condition.await();
            // printBar.run() outputs "bar". Do not change or remove this line.
            printBar.run();
            flag = false;
            condition.signalAll();
            lock.unlock();
        }

    }

    static class PrintFoo implements Runnable{
        @Override
        public void run() {
            System.out.print("foo");
        }
    }

    static class PrintBar implements Runnable{
        @Override
        public void run() {
            System.out.print("bar");
        }
    }
}